using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Threading;
using Needle.Utils.Extensions;

namespace Needle.Simulation
{
    [DebuggerNonUserCode]
    [DebuggerStepThrough]
    public class Task
    {

        #region factory methods

        public static Task Suspend(int processId, Action action)
        {
            return new Task(processId, TaskType.Suspend, TimeSpan.Zero, null, action);
        }

        public static Task Delay(int processId, TimeSpan delay, Action action)
        {
            return new Task(processId, TaskType.Delay, delay, null, action);
        }

        public static Task RaiseEvent(int processId, string eventName, Action action)
        {
            return new Task(processId, TaskType.RaiseEvent, TimeSpan.Zero, eventName, action);
        }

        public static Task WaitEvent(int processId, string eventName, Action action)
        {
            return new Task(processId, TaskType.WaitEvent, TimeSpan.Zero, eventName, action);
        }

        #endregion

        #region constructor

        private static long nextTaskId;

        private Task(int processId, TaskType type, TimeSpan delay, string eventName, Action action)
        {
            Id = nextTaskId++;
            this.ProcessId = processId;
            this.Type = type;
            this.DelayAmount = delay;
            this.EventName = eventName;
            this.Action = action;
        }

        #endregion

        #region properties

        public long Id { get; private set; }
        public int ProcessId { get; private set; }
        public TaskType Type { get; private set; }
        public TimeSpan DelayAmount { get; private set; }
        public string EventName { get; private set; }
        internal TimeSpan Time { get; set; }
        internal Action Action { get; set; }

        #endregion

        #region methods

        public void Execute()
        {
            if (Action != null)
                Action();
        }

        public override string ToString()
        {
            switch (Type)
            {
                case TaskType.RaiseEvent:
                    return "t# {0} {1} {2}".FormattedWith(Id, Type, EventName);
                case TaskType.WaitEvent:
                    return "t# {0} {1} {2}".FormattedWith(Id, Type, EventName);
                case TaskType.Delay:
                    return "t# {0} {1} {2}, Resume at {3}".FormattedWith(Id, Type, DelayAmount, Time);
                case TaskType.Suspend:
                    return "t# {0} {1} {2}".FormattedWith(Id, Type);
            }
            return base.ToString();
        }

        #endregion

    }
}
